﻿using RBAC.Domain;
using RBAC.ErrorCode;
using RBAC.Host.Dto.Input;
using RBAC.Host.Dto.Output;
using RBAC.Interstructrue.Base;
using Yitter.IdGenerator;
using AutoMapper;
using System.Security.Cryptography;
using System.Text;
using MD5Hash;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

namespace RBAC.Host.Service
{
    public class Service : IService
    {
        private readonly IBaseRepository<UserRoleModel> userRoleRepository;
        private readonly IBaseRepository<RolePermissionModel> roleperimissionRepository;
        private readonly IBaseRepository<PermissionModel> permissionRepository;
        private readonly IBaseRepository<RoleModel> roleRepository;
        private readonly IBaseRepository<UserModel> userRepository;
        private readonly IMapper mapper;
        private readonly IConfiguration _config;

        public Service(
            IBaseRepository<UserRoleModel> userRoleRepository,
            IBaseRepository<RolePermissionModel> roleperimissionRepository,
            IBaseRepository<PermissionModel> permissionRepository,
            IBaseRepository<RoleModel> roleRepository,
            IBaseRepository<UserModel> userRepository,
            IMapper mapper,
            IConfiguration config)
        {
            this.userRoleRepository = userRoleRepository;
            this.roleperimissionRepository = roleperimissionRepository;
            this.permissionRepository = permissionRepository;
            this.roleRepository = roleRepository;
            this.userRepository = userRepository;
            this.mapper = mapper;
            _config = config;
        }

        /// <summary>
        /// 添加权限
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public APIResult<int> AddPermission(AddPermissionInput input)
        {
            APIResult<int> res = new APIResult<int>();
            var userrole = userRoleRepository.Create(new UserRoleModel
            {
                Id = YitIdHelper.NextId(),
                UserId = input.UserId,
                RoleId = input.RoleId,
            });

            int count = 0;
            foreach (var permissionId in input.PermissionIds)
            {
                var rolePermission = roleperimissionRepository.Create(new RolePermissionModel
                {
                    Id = YitIdHelper.NextId(),
                    RoleId = input.RoleId,
                    PermissionId = permissionId,
                });
                count += rolePermission;
            }

            res.Code = APIEnums.Success;
            res.Data = count;
            res.Msg = "添加成功";
            return res;
        }
        /// <summary>
        /// 获取权限列表
        /// </summary>
        /// <param name="permissionName"></param>
        /// <returns></returns>
        public APIResult<List<PermissionDto>> GetPermissionList(string? permissionName = null)
        {
            var list = permissionRepository.GetALL().Where(x => !x.IsDeleted);
            if (!string.IsNullOrEmpty(permissionName))
            {
                list = list.Where(x => x.PermissionName.Contains(permissionName));
            }
            return new APIResult<List<PermissionDto>>
            {
                Code = APIEnums.Success,
                Data = mapper.Map<List<PermissionDto>>(list.ToList()),
                Msg = "获取权限列表成功"
            };
        }
        /// <summary>
        /// 获取角色列表
        /// </summary>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public APIResult<List<RoleListDto>> GetRoleList(string? roleName = null)
        {
            var list = roleRepository.GetALL().Where(x => !x.IsDeleted);
            if (!string.IsNullOrEmpty(roleName))
            {
                list = list.Where(x => x.RoleName.Contains(roleName));
            }
            
            var roles = list.ToList();
            var roleDtos = mapper.Map<List<RoleListDto>>(roles);
            
            // 为每个角色添加其对应的权限
            foreach (var roleDto in roleDtos)
            {
                // 获取角色对应的所有权限ID
                var permissionIds = roleperimissionRepository.GetALL()
                    .Where(x => x.RoleId == roleDto.Id && !x.IsDeleted)
                    .Select(x => x.PermissionId)
                    .ToList();
                
                // 获取所有权限详情
                if (permissionIds.Any())
                {
                    var permissions = permissionRepository.GetALL()
                        .Where(p => permissionIds.Contains(p.Id) && !p.IsDeleted)
                        .ToList();
                    
                    roleDto.Permissions = mapper.Map<List<PermissionDto>>(permissions);
                }
            }
            
            return new APIResult<List<RoleListDto>>
            {
                Data = roleDtos,
                Msg = "获取角色列表成功",
                Code = APIEnums.Success
            };
        }

        public APIResult<UserLoginDto> UserLogin(UserLoginInputDto input)
        {
            string md5Pwd = input.Password.GetMD5();
            var user = userRepository.GetALL().
                FirstOrDefault(x => x.UserName == input.UserName && x.Password == md5Pwd && !x.IsDeleted);
            
            if (user == null)
            {
                return new APIResult<UserLoginDto>
                {
                    Msg = "用户名或密码错误",
                    Code = APIEnums.Fail
                };
            }
            
            // 获取用户角色
            var userRole = userRoleRepository.GetALL()
                .FirstOrDefault(x => x.UserId == user.Id && !x.IsDeleted);
        
            if (userRole == null)
            {
                return new APIResult<UserLoginDto>
                {
                    Msg = "该用户未分配角色",
                    Code = APIEnums.Fail
                };
            }
        
            // 获取角色信息
            var role = roleRepository.GetModel(userRole.RoleId);
        
            var dto = mapper.Map<UserLoginDto>(user);
            dto.RoleId = userRole.RoleId;
            dto.RoleName = role?.RoleName;
            dto.Token = GenerateJwtToken(dto);
            return new APIResult<UserLoginDto>
            {
                Msg = "登录成功",
                Data = dto,
                Code = APIEnums.Success
            };
        }
        /// <summary>
        /// 生成JWT令牌
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public string GenerateJwtToken(UserLoginDto user)
        {
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JwtSettings:SecretKey"]));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

            var claims = new[]
            {
                new Claim("UserName", user.UserName),
                new Claim("UserId", user.Id.ToString()),
                new Claim("RoleId", user.RoleId.ToString()),
                new Claim("RoleName", user.RoleName)
            };

            var token = new JwtSecurityToken(
                issuer: _config["JwtSettings:Issuer"],
                audience: _config["JwtSettings:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(120),
                signingCredentials: credentials
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }
        // 用户管理
        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public APIResult<List<UserDto>> GetUserList(string? userName = null)
        {
            APIResult<List<UserDto>> res = new APIResult<List<UserDto>>();

            var list = userRepository.GetALL().Where(x => !x.IsDeleted);
            if (!string.IsNullOrEmpty(userName))
            {
                list = list.Where(x => x.UserName.Contains(userName));
            }
            res.Code = APIEnums.Success;
            res.Data = mapper.Map<List<UserDto>>(list.ToList());
            res.Msg = "获取用户列表成功";
            return res;

        }
        /// <summary>
        ///     获取用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public APIResult<UserDto> GetUser(long id)
        {
            APIResult<UserDto> res = new APIResult<UserDto>();
            var user = userRepository.GetModel(id);
            res.Code = APIEnums.Success;
            res.Data = mapper.Map<UserDto>(user);
            res.Msg = "获取用户成功";
            return res;
        }
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="userDto"></param>
        /// <returns></returns>
        public APIResult<int> AddUser(UserDto userDto)
        {
            APIResult<int> res = new APIResult<int>();
            var user = mapper.Map<UserModel>(userDto);
            user.Id = YitIdHelper.NextId();
            user.IsDeleted = false;
            res.Code = APIEnums.Success;
            res.Data = userRepository.Create(user);
            res.Msg = "添加用户成功";
            return res;
        }
        public APIResult<int> UpdateUser(UserDto userDto)
        {
            var user = userRepository.GetModel(userDto.Id);
            if (user == null)
            {
                return new APIResult<int>
                {
                    Msg = "用户不存在",
                    Code = APIEnums.Fail

                };

            }
            user.UserName = userDto.UserName;

            return new APIResult<int>
            {
                Msg = "修改用户成功",
                Code = APIEnums.Success,
                Data = userRepository.Update(user),
            };

        }
        public APIResult<int> DeleteUser(long id)
        {
            var user = userRepository.GetModel(id);
            if (user == null)
            {
                return new APIResult<int>
                {
                    Msg = "用户不存在",
                    Code = APIEnums.Fail
                };
            }
            user.IsDeleted = true;
            return new APIResult<int>
            {
                Msg = "删除用户成功",
                Code = APIEnums.Success,
                Data = userRepository.Update(user)
            };

        }
        // 角色管理
        public APIResult<RoleListDto> GetRole(long id)
        {
            var role = roleRepository.GetModel(id);
            if (role == null)
            {
                return new APIResult<RoleListDto>
                {
                    Msg = "角色不存在",
                    Code = APIEnums.Fail
                };
            }
            
            var roleDto = mapper.Map<RoleListDto>(role);
            
            // 获取角色对应的所有权限ID
            var permissionIds = roleperimissionRepository.GetALL()
                .Where(x => x.RoleId == id && !x.IsDeleted)
                .Select(x => x.PermissionId)
                .ToList();
                
            // 获取所有权限详情
            if (permissionIds.Any())
            {
                var permissions = permissionRepository.GetALL()
                    .Where(p => permissionIds.Contains(p.Id) && !p.IsDeleted)
                    .ToList();
                
                roleDto.Permissions = mapper.Map<List<PermissionDto>>(permissions);
            }
            
            return new APIResult<RoleListDto>
            {
                Msg = "获取角色成功",
                Code = APIEnums.Success,
                Data = roleDto
            };
        }
        public APIResult<int> AddRole(RoleDto roleDto)
        {
            try
            {
                // 获取DbContext以开启事务
                var dbContext = ((BaseRepository<RoleModel>)roleRepository).GetDbContext();
                
                // 开启事务
                using var transaction = dbContext.Database.BeginTransaction();
                try
                {
                    // 1. 创建角色
                    var role = mapper.Map<RoleModel>(roleDto);
                    role.Id = YitIdHelper.NextId();
                    role.IsDeleted = false;
                    role.CreateTime = DateTime.Now;
                    dbContext.Set<RoleModel>().Add(role);
                    dbContext.SaveChanges();
                    
                    // 2. 添加角色权限关联
                    if (roleDto.PermissionIds != null && roleDto.PermissionIds.Any())
                    {
                        foreach (var permissionId in roleDto.PermissionIds)
                        {
                            // 检查权限是否存在
                            var permission = permissionRepository.GetModel(permissionId);
                            if (permission != null && !permission.IsDeleted)
                            {
                                var rolePermission = new RolePermissionModel
                                {
                                    Id = YitIdHelper.NextId(),
                                    RoleId = role.Id,
                                    PermissionId = permissionId,
                                    IsDeleted = false,
                                    CreateTime = DateTime.Now
                                };
                                dbContext.Set<RolePermissionModel>().Add(rolePermission);
                            }
                        }
                        dbContext.SaveChanges();
                    }
                    
                    // 提交事务
                    transaction.Commit();
                    
                    return new APIResult<int>()
                    {
                        Msg = "添加角色及权限成功",
                        Code = APIEnums.Success,
                        Data = 1
                    };
                }
                catch (Exception ex)
                {
                    // 回滚事务
                    transaction.Rollback();
                    return new APIResult<int>()
                    {
                        Msg = $"添加角色失败: {ex.Message}",
                        Code = APIEnums.Fail,
                        Data = 0
                    };
                }
            }
            catch (Exception ex)
            {
                return new APIResult<int>()
                {
                    Msg = $"系统错误: {ex.Message}",
                    Code = APIEnums.Fail,
                    Data = 0
                };
            }
        }
        public APIResult<int> UpdateRole(RoleDto roleDto)
        {
            var role = roleRepository.GetModel(roleDto.Id);
            if (role == null)
            {
                return new APIResult<int>
                {
                    Msg = "角色不存在",
                    Code = APIEnums.Fail
                };
            }
            role.RoleName = roleDto.RoleName;
            return new APIResult<int>
            {
                Msg = "修改角色成功",
                Code = APIEnums.Success,
                Data = roleRepository.Update(role)
            };


        }
        public APIResult<int> DeleteRole(long id)
        {
            var role = roleRepository.GetModel(id);
            if (role == null)
            {
                return new APIResult<int>
                {
                    Msg = "角色不存在",
                    Code = APIEnums.Fail
                };
            }
            role.IsDeleted = true;
            return new APIResult<int>
            {
                Msg = "删除角色成功",
                Code = APIEnums.Success,
                Data = roleRepository.Update(role)
            };

        }
        // 权限管理
        public APIResult<PermissionDto> GetPermission(long id)
        {
            var permission = permissionRepository.GetModel(id);
            return new APIResult<PermissionDto>()
            {
                Msg = "获取权限成功",
                Code = APIEnums.Success,
                Data = mapper.Map<PermissionDto>(permission)
            };

        }
        public APIResult<int> AddPermission(PermissionDto permissionDto)
        {
            var permission = mapper.Map<PermissionModel>(permissionDto);
            permission.Id = YitIdHelper.NextId();
            permission.IsDeleted = false;
            return new APIResult<int>
            {
                Msg = "添加权限成功",
                Code = APIEnums.Success,
                Data = permissionRepository.Create(permission)
            };

        }
        /// <summary>
        /// 修改权限
        /// </summary>
        /// <param name="permissionDto"></param>
        /// <returns></returns>
        public APIResult<int> UpdatePermission(PermissionDto permissionDto)
        {
            var permission = permissionRepository.GetModel(permissionDto.Id);
            if (permission == null)
            {
                return new APIResult<int>
                {
                    Msg = "权限不存在",
                    Code = APIEnums.Fail
                };
            }
            permission.PermissionName = permissionDto.PermissionName;
            permission.MenuUrl = permissionDto.MenuUrl;
            permission.ParentId = permissionDto.ParentId;
            permission.MenuID = permissionDto.MenuID;
            return new APIResult<int>
            {
                Msg = "修改权限成功",
                Code = APIEnums.Success,
                Data = permissionRepository.Update(permission)
            };

        }
        /// <summary>
        /// 删除权限
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public APIResult<int> DeletePermission(long id)
        {
            var permission = permissionRepository.GetModel(id);
            if (permission == null)
            {
                return new APIResult<int>
                {
                    Msg = "权限不存在",
                    Code = APIEnums.Fail
                };
            }
            permission.IsDeleted = true;
            return new APIResult<int>
            {
                Msg = "删除权限成功",
                Code = APIEnums.Success,
                Data = permissionRepository.Update(permission)
            };

        }
        // 用户角色分配
        public APIResult<int> AssignRoleToUser(long userId, long roleId)
        {
            var userRole = userRoleRepository.GetALL().FirstOrDefault(x => x.UserId == userId && x.RoleId == roleId && !x.IsDeleted);
            if (userRole != null)
            {
                return new APIResult<int>()
                {
                    Msg = "角色已存在",
                    Code = APIEnums.Fail

                };
            }
            return new APIResult<int>
            {
                Msg = "分配角色成功",
                Code = APIEnums.Success,
                Data = userRoleRepository.Create(new UserRoleModel
                {
                    Id = YitIdHelper.NextId(),
                    UserId = userId,
                    RoleId = roleId,
                    IsDeleted = false
                })
            };

        }
        /// <summary>
        /// 移除角色
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public APIResult<int> RemoveRoleFromUser(long userId, long roleId)
        {
            var userRole = userRoleRepository.GetALL().FirstOrDefault(x => x.UserId == userId && x.RoleId == roleId && !x.IsDeleted);
            if (userRole == null)
            {
                return new APIResult<int>()
                {
                    Msg = "角色不存在",
                    Code = APIEnums.Fail
                };
            }
            userRole.IsDeleted = true;
            return new APIResult<int>()
            {
                Msg = "移除角色成功",
                Code = APIEnums.Success,
                Data = userRoleRepository.Update(userRole)
            };

        }
        public APIResult<List<RoleDto>> GetUserRoles(long userId)
        {
            var roleIds = userRoleRepository.GetALL()
                .Where(x => x.UserId == userId && !x.IsDeleted)
                .Select(x => x.RoleId).ToList();
                
            var roles = roleRepository.GetALL()
                .Where(x => roleIds.Contains(x.Id) && !x.IsDeleted)
                .ToList();
                
            var roleDtos = mapper.Map<List<RoleDto>>(roles);
            
            // 为每个角色添加对应的权限
            foreach (var roleDto in roleDtos)
            {
                // 获取角色对应的所有权限ID
                var permissionIds = roleperimissionRepository.GetALL()
                    .Where(x => x.RoleId == roleDto.Id && !x.IsDeleted)
                    .Select(x => x.PermissionId)
                    .ToList();
                
                // 获取所有权限详情
                if (permissionIds.Any())
                {
                    var permissions = permissionRepository.GetALL()
                        .Where(p => permissionIds.Contains(p.Id) && !p.IsDeleted)
                        .ToList();
                    
                    roleDto.Permissions = mapper.Map<List<PermissionDto>>(permissions);
                }
            }
            
            return new APIResult<List<RoleDto>>
            {
                Msg = "获取用户角色成功",
                Code = APIEnums.Success,
                Data = roleDtos
            };
        }
        // 角色权限分配
        public APIResult<int> AssignPermissionToRole(long roleId, long permissionId)
        {
            var rp = roleperimissionRepository.GetALL().FirstOrDefault(x => x.RoleId == roleId && x.PermissionId == permissionId && !x.IsDeleted);
            if (rp != null)
            {
                return new APIResult<int>
                {
                    Msg = "权限已存在",
                    Code = APIEnums.Fail
                };
            }
            return new APIResult<int>
            {
                Msg = "权限已存在",
                Code = APIEnums.Fail,
                Data = roleperimissionRepository.Create(new RolePermissionModel
                {
                    Id = YitIdHelper.NextId(),
                    RoleId = roleId,
                    PermissionId = permissionId,
                    IsDeleted = false
                })
            };

        }
        public APIResult<int> RemovePermissionFromRole(long roleId, long permissionId)
        {
            var rp = roleperimissionRepository.GetALL().FirstOrDefault(x => x.RoleId == roleId && x.PermissionId == permissionId && !x.IsDeleted);
            if (rp == null)
            {
                return new APIResult<int>
                {
                    Msg = "权限不存在",
                    Code = APIEnums.Fail
                };
            }
            rp.IsDeleted = true;
            return new APIResult<int>
            {
                Msg = "移除权限成功",
                Code = APIEnums.Success,
                Data = roleperimissionRepository.Update(rp)
            };

        }
        public APIResult<List<PermissionDto>> GetRolePermissions(long roleId)
        {
            var permissionIds = roleperimissionRepository.GetALL().Where(x => x.RoleId == roleId && !x.IsDeleted).Select(x => x.PermissionId).ToList();
            var permissions = permissionRepository.GetALL().Where(x => permissionIds.Contains(x.Id) && !x.IsDeleted).ToList();
            return new APIResult<List<PermissionDto>>
            {
                Msg = "获取角色权限成功",
                Code = APIEnums.Success,
                Data = permissions.Select(x => mapper.Map<PermissionDto>(x)).ToList()
            };

        }
        // 查询用户所有权限
        public APIResult<List<PermissionDto>> GetUserPermissions(long userId)
        {
            var roleIds = userRoleRepository.GetALL().Where(x => x.UserId == userId && !x.IsDeleted).Select(x => x.RoleId).ToList();
            var permissionIds = roleperimissionRepository.GetALL().Where(x => roleIds.Contains(x.RoleId) && !x.IsDeleted).Select(x => x.PermissionId).Distinct().ToList();
            var permissions = permissionRepository.GetALL().Where(x => permissionIds.Contains(x.Id) && !x.IsDeleted).ToList();
            return new APIResult<List<PermissionDto>>
            {
                Msg = "获取用户权限成功",
                Code = APIEnums.Success,
                Data = permissions.Select(x => mapper.Map<PermissionDto>(x)).ToList()
            };
        }


    }
}
